#!/usr/bin/env node

// 全面PWM诊断和修复脚本
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
const fs = require('fs');

console.log("🔧 全面PWM诊断和修复脚本");

async function runCommand(command, options = {}) {
  try {
    const result = await execAsync(command, options);
    return { success: true, stdout: result.stdout, stderr: result.stderr };
  } catch (error) {
    return { success: false, error: error.message, stdout: '', stderr: error.stderr || '' };
  }
}

async function checkSystemEnvironment() {
  console.log("\n🔍 系统环境检查...");
  
  // 1. 检查设备型号
  try {
    const model = fs.readFileSync('/proc/device-tree/model', 'utf8');
    console.log(`设备型号: ${model.trim()}`);
  } catch (error) {
    console.log("无法读取设备型号");
  }
  
  // 2. 检查WiringPi版本
  try {
    const version = await execAsync('gpio -v');
    console.log(`WiringPi版本: ${version.stdout.split('\n')[0]}`);
  } catch (error) {
    console.log("WiringPi未安装或不可用");
  }
  
  // 3. 检查Node.js版本
  try {
    const nodeVersion = await execAsync('node --version');
    console.log(`Node.js版本: ${nodeVersion.stdout.trim()}`);
  } catch (error) {
    console.log("无法获取Node.js版本");
  }
  
  // 4. 检查pigpio进程
  try {
    const pigpio = await execAsync('ps aux | grep pigpiod | grep -v grep');
    if (pigpio.stdout) {
      console.log("⚠️  发现pigpio后台进程，可能干扰WiringPi:");
      console.log(pigpio.stdout);
    } else {
      console.log("✅ 未发现pigpio后台进程");
    }
  } catch (error) {
    console.log("检查pigpio进程时出错");
  }
}

async function testGPIOFunctionality() {
  console.log("\n🔌 GPIO功能测试...");
  
  try {
    // 测试引脚12 (舵机)
    await execAsync('gpio -g mode 12 out');
    await execAsync('gpio -g write 12 1');
    console.log("✅ GPIO 12 (舵机) 高电平输出正常");
    await execAsync('gpio -g write 12 0');
    
    // 测试引脚13 (电调)
    await execAsync('gpio -g mode 13 out');
    await execAsync('gpio -g write 13 1');
    console.log("✅ GPIO 13 (电调) 高电平输出正常");
    await execAsync('gpio -g write 13 0');
    
    console.log("✅ GPIO功能测试通过");
    return true;
  } catch (error) {
    console.log("❌ GPIO功能测试失败:", error.message);
    return false;
  }
}

async function verifyPWMSignals() {
  console.log("\n📡 PWM信号验证...");
  
  try {
    // 初始化引脚
    await execAsync('gpio -g mode 12 out');
    await execAsync('gpio -g mode 13 out');
    
    // 测试标准舵机信号 (1.5ms中性)
    console.log("测试标准舵机信号 (1.5ms中性)...");
    await sendStandardPWM(12, 1.5, 2000); // 舵机
    await sendStandardPWM(13, 1.5, 2000); // 电调
    
    // 测试前进信号 (1.7ms)
    console.log("测试前进信号 (1.7ms)...");
    await sendStandardPWM(13, 1.7, 2000);
    
    // 测试右转信号 (1.8ms)
    console.log("测试右转信号 (1.8ms)...");
    await sendStandardPWM(12, 1.8, 2000);
    
    console.log("✅ PWM信号验证完成");
    return true;
  } catch (error) {
    console.log("❌ PWM信号验证失败:", error.message);
    return false;
  }
}

async function testHardwarePWM() {
  console.log("\n⚙️  硬件PWM测试...");
  
  try {
    // 测试硬件PWM模式
    await execAsync('gpio -g mode 12 pwm');
    await execAsync('gpio -g pwm 12 512');
    console.log("✅ 硬件PWM (引脚12) 设置成功");
    
    await execAsync('gpio -g mode 13 pwm');
    await execAsync('gpio -g pwm 13 512');
    console.log("✅ 硬件PWM (引脚13) 设置成功");
    
    // 恢复输出模式
    await execAsync('gpio -g mode 12 out');
    await execAsync('gpio -g mode 13 out');
    
    console.log("✅ 硬件PWM测试完成");
    return true;
  } catch (error) {
    console.log("⚠️  硬件PWM测试失败:", error.message);
    // 恢复输出模式
    try {
      await execAsync('gpio -g mode 12 out');
      await execAsync('gpio -g mode 13 out');
    } catch (e) {}
    return false;
  }
}

async function calibrateESC() {
  console.log("\n🔧 电调校准程序...");
  
  try {
    // 初始化引脚
    await execAsync('gpio -g mode 13 out');
    
    console.log("步骤1: 发送最大油门信号 (2.0ms) - 请听电调声音...");
    await sendStandardPWM(13, 2.0, 5000); // 保持5秒
    
    console.log("步骤2: 发送最小油门信号 (1.0ms) - 请听电调声音...");
    await sendStandardPWM(13, 1.0, 5000); // 保持5秒
    
    console.log("步骤3: 发送中性信号 (1.5ms)...");
    await sendStandardPWM(13, 1.5, 2000); // 保持2秒
    
    console.log("✅ 电调校准完成");
    return true;
  } catch (error) {
    console.log("❌ 电调校准失败:", error.message);
    return false;
  }
}

async function comprehensiveControlTest() {
  console.log("\n🎮 综合控制测试...");
  
  try {
    // 初始化引脚
    await execAsync('gpio -g mode 12 out');
    await execAsync('gpio -g mode 13 out');
    
    console.log("1. 发送中性信号...");
    await sendStandardPWM(12, 1.5, 1000); // 舵机中性
    await sendStandardPWM(13, 1.5, 1000); // 电调中性
    
    console.log("2. 发送前进信号...");
    await sendStandardPWM(13, 1.7, 2000); // 电调前进
    
    console.log("3. 发送转向信号...");
    await sendStandardPWM(12, 1.8, 1000); // 舵机右转
    
    console.log("4. 回到中性...");
    await sendStandardPWM(12, 1.5, 1000); // 舵机中性
    await sendStandardPWM(13, 1.5, 1000); // 电调中性
    
    console.log("✅ 综合控制测试完成");
    return true;
  } catch (error) {
    console.log("❌ 综合控制测试失败:", error.message);
    return false;
  }
}

// 发送标准PWM信号
async function sendStandardPWM(pin, dutyCycleMs, durationMs) {
  const periodMs = 20; // 50Hz = 20ms周期
  const highTimeMs = dutyCycleMs;
  const lowTimeMs = periodMs - dutyCycleMs;
  
  const cycles = Math.floor(durationMs / periodMs);
  
  for (let i = 0; i < cycles; i++) {
    await execAsync(`gpio -g write ${pin} 1`);
    await sleep(highTimeMs);
    await execAsync(`gpio -g write ${pin} 0`);
    await sleep(lowTimeMs);
  }
}

// 精确延时函数（毫秒）
function sleep(ms) {
  return new Promise(resolve => {
    const start = Date.now();
    while (Date.now() - start < ms) {
      // 空循环等待
    }
    resolve();
  });
}

async function checkProjectConfiguration() {
  console.log("\n📄 项目配置检查...");
  
  try {
    // 检查配置文件
    const configPath = '/home/pi/.network-rc/config.json';
    if (fs.existsSync(configPath)) {
      const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
      console.log("✅ 配置文件存在");
      
      // 检查通道配置
      if (config.channelList) {
        const escChannel = config.channelList.find(ch => ch.id === "电调");
        const servoChannel = config.channelList.find(ch => ch.id === "舵机");
        
        if (escChannel) {
          console.log(`电调配置: 引脚${escChannel.pin}, 类型${escChannel.type}`);
        }
        
        if (servoChannel) {
          console.log(`舵机配置: 引脚${servoChannel.pin}, 类型${servoChannel.type}`);
        }
      }
    } else {
      console.log("⚠️  配置文件不存在，使用默认配置");
    }
  } catch (error) {
    console.log("❌ 配置文件检查失败:", error.message);
  }
}

async function fixCommonIssues() {
  console.log("\n🔨 常见问题修复...");
  
  try {
    // 1. 停止可能干扰的pigpio进程
    try {
      await execAsync('sudo killall pigpiod 2>/dev/null || true');
      console.log("✅ 已停止pigpio进程");
    } catch (error) {
      console.log("ℹ️  未发现pigpio进程");
    }
    
    // 2. 重新初始化GPIO引脚
    await execAsync('gpio -g mode 12 out');
    await execAsync('gpio -g mode 13 out');
    console.log("✅ GPIO引脚重新初始化");
    
    // 3. 发送初始化信号
    await sendStandardPWM(12, 1.5, 1000);
    await sendStandardPWM(13, 1.5, 1000);
    console.log("✅ 发送初始化信号");
    
    console.log("✅ 常见问题修复完成");
    return true;
  } catch (error) {
    console.log("❌ 常见问题修复失败:", error.message);
    return false;
  }
}

async function main() {
  console.log("🚀 开始全面PWM诊断和修复");
  
  // 执行所有诊断步骤
  await checkSystemEnvironment();
  const gpioOk = await testGPIOFunctionality();
  const pwmOk = await verifyPWMSignals();
  const hwPwmOk = await testHardwarePWM();
  await checkProjectConfiguration();
  
  console.log("\n📋 诊断结果:");
  console.log(`  GPIO功能: ${gpioOk ? '✅' : '❌'}`);
  console.log(`  PWM信号: ${pwmOk ? '✅' : '❌'}`);
  console.log(`  硬件PWM: ${hwPwmOk ? '✅' : '⚠️'}`);
  
  // 如果基本测试通过，进行修复和校准
  if (gpioOk && pwmOk) {
    console.log("\n🔧 开始修复和校准...");
    await fixCommonIssues();
    const calOk = await calibrateESC();
    const controlOk = await comprehensiveControlTest();
    
    console.log("\n📊 最终结果:");
    console.log(`  问题修复: ✅`);
    console.log(`  电调校准: ${calOk ? '✅' : '⚠️'}`);
    console.log(`  控制测试: ${controlOk ? '✅' : '⚠️'}`);
    
    if (calOk && controlOk) {
      console.log("\n🎉 PWM控制问题已解决！");
      console.log("\n💡 使用建议:");
      console.log("   1. 如果问题再次出现，重新运行此诊断脚本");
      console.log("   2. 确保电调电源充足");
      console.log("   3. 定期检查硬件连接");
    } else {
      console.log("\n⚠️  问题可能需要进一步检查:");
      console.log("   1. 检查电调和电机硬件");
      console.log("   2. 确认电源供应充足");
      console.log("   3. 参考电调说明书进行特殊校准");
    }
  } else {
    console.log("\n❌ 基础功能测试失败，请检查硬件连接和系统配置");
  }
}

main();